# 
#   Mindset : reflect how boid will move relatively to environement
# 
# Basic mind set       
# Execute all behaviours in sequential order

from behaviours import *

class MindSet() :
  def __init__(self,scene=None):
    self.boid = None
    self.behaviours = []
    self.scene = scene
    
  def move(self):
    acceleration = Vector(0.0,0.0,0.0)
    for b in self.behaviours:
      if b.boid is None:
        b.boid = self.boid
      if b.scene is None :
        b.scene = self.scene
      acceleration += b.get_acceleration()
    return acceleration
    
  def set_boid(boid):
    self.boid = boid
    for b in self.behaviours:
      b.boid = boid
# 
#     Camera focus mindset : try to stay in the middle of the scene boids
#     
class CameraFocusMindset(MindSet):
  def __init__(self,scene=None,boid=None):
    MindSet.__init__(self,scene)
    self.behaviours.append(Cohesion(boid=boid,scene=scene,factor=1.0))
   
#
#   Camera Mindset  : stay at a relative offset from a camera focus boid
#    
class CameraMindSet(MindSet):
  def __init__(self,scene=None,boid=None,offset=Vector(0.0,0.0,0.0),target=None):
    MindSet.__init__(self,scene)
    self.behaviours.append(OffsetFollower(boid=boid,scene=scene,factor=1.0,offset=offset,target=target))


#       Basic flocking mindset
#       include cohesion, separation
#       prudence impact separation (the less prudent, le closest it is allowed to go)
#       sociability impact cohesion (the more sociable, the more it tries to stay close to the others)
#       wandering is used to give freedom (vs sociability)
    
class BasicFlockingMindset(MindSet):
  def __init__(self,scene=None,boid=None,prudent=1.0,sociable=1.0):
    MindSet.__init__(self,scene)
    self.behaviours.append(Cohesion(boid=boid,scene=scene,factor=0.05 * sociable))
    self.behaviours.append(Separation(boid=boid,scene=scene,factor=0.5 + 0.5 * prudent))
    self.behaviours.append(Wandering(boid=boid,scene=scene,factor=0.05*(1-sociable)))
    self.behaviours.append(Alignment(boid=boid,scene=scene,factor=(0.125*sociable)))
    self.behaviours.append(Containment(boid=boid,scene=scene,factor=0.5 + 0.5 * prudent))
    
